package com.clp.protocol.iec104.apdu;

import com.clp.protocol.iec104.apdu.apci.SApci;
import com.clp.protocol.iec104.definition.ApduType;
import com.clp.protocol.iec104.definition.ConstVal;
import com.clp.protocol.core.pdu.nbytepdu.BaseNBytePduClip;
import com.clp.protocol.core.pdu.ByteToStringFormat;
import io.netty.buffer.ByteBuf;
import lombok.*;

import java.util.Objects;
import java.util.function.Consumer;

/**
 * S帧
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SApdu extends Apdu {
    private SApci sApci;

    @Override
    public ApduType apduType() {
        return ApduType.SType;
    }

    @Override
    public SApdu refreshFrom(ByteBuf buf) {
        this.sApci = new SApci().refreshFrom(buf);
        return this;
    }

    @Override
    public boolean isValid() {
        return sApci != null && sApci.isValid();
    }

    @Override
    public void writeBytesTo(ByteBuf buf) {
        sApci.writeBytesTo(buf);
        // 注意：最后要设置长度
        buf.setByte(buf.readerIndex() + 1, buf.readableBytes() - ConstVal.HEAD_LEN - ConstVal.LENGTH_LEN);
    }

    @Override
    public void writeFormattedByteStringsTo(StringBuilder sb, String frameClipBytesSeparator, String byteSeparator, ByteToStringFormat byteFormat) {
        sApci.writeFormattedByteStringsTo(sb, frameClipBytesSeparator, byteSeparator, byteFormat);
    }

    @Override
    public void writeSimpleDescriptionTo(StringBuilder sb) {
        sb.append("     <").append(apduType().getDesc()).append("> ");
        sApci.writeSimpleDescriptionTo(sb);
    }

    @Override
    public void writeDetailDescriptionTo(StringBuilder sb) {
        sb.append("     <帧类型：").append(apduType().getDesc()).append("> ");
        sApci.writeDetailDescriptionTo(sb);
    }

    @Override
    protected void forEachOneLevelChild(Consumer<BaseNBytePduClip<?>> consumer) {
        consumer.accept(sApci);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SApdu sApdu = (SApdu) o;
        return Objects.equals(sApci, sApdu.sApci);
    }

    @Override
    public int hashCode() {
        return Objects.hash(sApci);
    }
}
